/*
 * CloudBank Mobile Knowledge Sharing for Language Learners
 * Supported by the JISC Rapid Innovation Programme #jiscri
 *
 * Copyright (C) 2010 University of Brighton
 *
 * Licensed under the GNU General Public License v3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/licenses/gpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package uk.ac.brighton.itrg.cloudbank;

import java.io.File;
import java.net.URLEncoder;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.text.SpannableString;
import android.text.format.Time;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class ActivityEdit extends Activity implements OnClickListener, OnFocusChangeListener
{
	private static final String TAG = ActivityEdit.class.getSimpleName();

	private Item mItem = new Item();
	private Item mBackupItem = new Item();
	private Item mLookupItem = new Item();
	
	private TextView txtItem, txtDescription, txtTags;
	private ImageView imgImage, imgAudio, imgLink;
	
	private MediaPlayer mPlayer;
	
	private ProgressDialog mProgress;
	private Handler mHandler; 
	

	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
        Logger.log(TAG + ".onCreate()");
        try
        {
        	setContentView(R.layout.edit);       	
        	
        	// get handles
        	txtItem = (TextView)findViewById(R.id.txtItem);
        	txtDescription = (TextView)findViewById(R.id.txtDescription);
        	txtTags = (TextView)findViewById(R.id.txtTags);
        	imgImage = (ImageView)findViewById(R.id.imgImage);
        	imgAudio = (ImageView)findViewById(R.id.imgAudio);
        	imgLink = (ImageView)findViewById(R.id.imgLink);
       		
	        // register listeners
	        imgAudio.setOnClickListener(this);
	        imgLink.setOnClickListener(this);
        	txtItem.setOnFocusChangeListener(this);
        	txtDescription.setOnFocusChangeListener(this);
        	txtTags.setOnFocusChangeListener(this);

	        // don't need a handle for these...
        	findViewById(R.id.btnCamera).setOnClickListener(this);
        	findViewById(R.id.btnRecord).setOnClickListener(this);
        	findViewById(R.id.btnBrowse).setOnClickListener(this);
        	findViewById(R.id.btnSave).setOnClickListener(this);
        	findViewById(R.id.btnBack).setOnClickListener(this);
        	

	        if (savedInstanceState != null) 
	        {
		        // restore from saved instance state.

	        	String s = savedInstanceState.getString("mItem");
	        	mItem.init(s);

	        	Logger.log("SavedInstanceData:mItem", s);

	        	s = savedInstanceState.getString("mBackupItem");
	        	mBackupItem.init(s);
	        	
	        	Logger.log("SavedInstanceData:mBackupItem", s);

	        	s = savedInstanceState.getString("txtItem");
	    		txtItem.setText(s);
	    		
	        	Logger.log("SavedInstanceData:txtItem", s);

	        	s = savedInstanceState.getString("txtDescription");
		        txtDescription.setText(s);

	        	Logger.log("SavedInstanceData:txtdescription", s);

		        s = savedInstanceState.getString("txtTags");
		        txtTags.setText(s);
		        
	        	Logger.log("SavedInstanceData:txtTags", s);
	        }
	        else   
        	{
	        	if(getIntent().hasExtra("mItem"))
	        	{
			        // we edit an existing item passed in by ActivityDetail 

	        		String s = getIntent().getExtras().getString("mItem");
		        	mItem.init(s); 

		        	Logger.log("getIntent().getExtras().Item", s);

		        	txtItem.setText(mItem.item);
			        txtDescription.setText(mItem.description);
			        txtTags.setText(mItem.tags);
	        	}
	        	else
	        	{
	        		// we add a new item: initialise tags with Default Post tags
	        		mItem.tags = CB.DEFAULT_TAGS; // might be "" 
	        		if(mItem.tags.length()>0)
	        		{
				        txtTags.setText(mItem.tags + " "); // ready to add more tags
	        		}
	        	}
	    		mBackupItem.init(mItem);  
        	}
   		
    		// init buttons  
	        if(mItem.image.length()>0) imgImage.setImageBitmap(Media.getTmpImage(64, 48));
	        if(mItem.audio.length()>0) imgAudio.setImageDrawable(getResources().getDrawable(R.drawable.edit_audio));
	        if(mItem.link.length()>0) imgLink.setImageDrawable(getResources().getDrawable(R.drawable.edit_link));
        }
        catch(Exception e)
        {
        	Logger.log(e);
        }
	}

    
	// ------------------------------------------
    // app becomes visible
	// ------------------------------------------
	public void onStart()
	{
		super.onStart();
        Logger.log(TAG + ".onStart()");
	}

	
	// ------------------------------------------
	// Save away the original text, so we still have it 
    // if the activity needs to be killed while paused.
	// ------------------------------------------
    protected void onSaveInstanceState(Bundle outState) 
    {
    	Logger.log(TAG + ".onSaveInstanceState()");

    	// item and backup item
    	String s = mItem.toString();
        outState.putString("mItem", s);

    	Logger.log("mItem", s);

    	s = mBackupItem.toString();
        outState.putString("mBackupItem", s);
        
    	Logger.log("mBackupItem", s);

    	// text fields
    	s = txtItem.getText().toString();
        outState.putString("txtItem", s);

    	Logger.log("txtItem", s);

    	s = txtDescription.getText().toString();
        outState.putString("txtDescription", s);

    	Logger.log("txtDescription", s);

    	s = txtTags.getText().toString();
        outState.putString("txtTags", s);

        Logger.log("txtTags", s);
    }
	

	// ------------------------------------------
    // app becomes invisible
	// ------------------------------------------
	public void onStop()
	{
		super.onStop();
        Logger.log(TAG + ".onStop()");
	}

	// ------------------------------------------
    // interface OnClickListener
	// ------------------------------------------
    public void onClick(View v) 
    {
        Logger.log(TAG + ".onClick()");

    	switch(v.getId())
    	{
    	
    	case R.id.imgAudio: 
            try 
            {
            	if(mItem.audio.length() > 0) 
            	{
            		
            		if (mPlayer == null)
            		{
            			mPlayer = MediaPlayer.create(this, Media.getTmpAudioUri());
            			mPlayer.setVolume(1.0f, 1.0f);
            		}

        			if(mPlayer.isPlaying())	mPlayer.stop();
        			else
        			{
                		Toast.makeText(this, "Playing audio...", Toast.LENGTH_SHORT).show();    
        				mPlayer.start();
        			}
            	}
            	else
            	{
    	        	new AlertDialog.Builder(ActivityEdit.this)
    	            .setMessage("No audio available. Press microphone icon to record audio.")
    	            .setPositiveButton("Close", new DialogInterface.OnClickListener() 
    	            {
    	                    public void onClick(DialogInterface dialog, int whichButton) 
    	                    {
    			            	// do nothing
    	                    } 
    	            }).show();
            	}            		
            } 
            catch (Exception e) 
            {
                Logger.log(e);
            }
    		break;
    		
    		
    		
    	case R.id.imgLink: 
            try 
            {
            	if(mItem.link.length() > 0) 
            	{
    	        	new AlertDialog.Builder(ActivityEdit.this)
    	            .setMessage(mItem.link)
    	            .setPositiveButton("Close", new DialogInterface.OnClickListener() 
    	            {
    	                    public void onClick(DialogInterface dialog, int whichButton) 
    	                    {
    			            	// do nothing
    	                    } 
    	            }).show();
            	}
            	else 
            	{
    	        	new AlertDialog.Builder(ActivityEdit.this)
    	            .setMessage("No link available. Press browse icon to add a link.")
    	            .setPositiveButton("Close", new DialogInterface.OnClickListener() 
    	            {
    	                    public void onClick(DialogInterface dialog, int whichButton) 
    	                    {
    			            	// do nothing
    	                    } 
    	            }).show();
            	}
            } 
            catch (Exception e) 
            {
                Logger.log(e);
            }
    		break;
    		
    		
    		
    	case R.id.btnCamera: 
    		
    		if(mItem.image.length() == 0) startCamera();
    		else
    		{
    	    	new AlertDialog.Builder(ActivityEdit.this)
    	        .setMessage("Replace existing image?")
    	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() 
    	        {
    	                public void onClick(DialogInterface dialog, int whichButton) 
    	                {
    	                	startCamera();
    	                } 
    	        })
    	        .setNegativeButton("No", new DialogInterface.OnClickListener() 
    	        {
    	                public void onClick(DialogInterface dialog, int whichButton) 
    	                {
    	                	// do nothing
    	                } 
    	        }).show();
    		}
    		break;
    		
    		
    		
    	case R.id.btnRecord: 

    		if(mItem.audio.length() == 0) startRecorder();
    		else
    		{
    	    	new AlertDialog.Builder(ActivityEdit.this)
    	        .setMessage("Replace existing audio recording?")
    	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() 
    	        {
    	                public void onClick(DialogInterface dialog, int whichButton) 
    	                {
    	                	startRecorder();
    	                } 
    	        })
    	        .setNegativeButton("No", new DialogInterface.OnClickListener() 
    	        {
    	                public void onClick(DialogInterface dialog, int whichButton) 
    	                {
    	                	// do nothing
    	                } 
    	        }).show();
    		}
    		break;
    		
    		
    		
    	case R.id.btnBrowse: 

    		if(mItem.link.length() == 0) startBrowser();
    		else
    		{
    	    	new AlertDialog.Builder(ActivityEdit.this)
    	        .setMessage("Replace existing link?")
    	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() 
    	        {
    	                public void onClick(DialogInterface dialog, int whichButton) 
    	                {
    	                	startBrowser();
    	                } 
    	        })
    	        .setNegativeButton("No", new DialogInterface.OnClickListener() 
    	        {
    	                public void onClick(DialogInterface dialog, int whichButton) 
    	                {
    	                	// do nothing
    	                } 
    	        }).show();
    		}
    		break;
    		
    		
    		
    	case R.id.btnSave: 
    		
            try 
            {
            	String s = txtItem.getText().toString().trim();
            	if(s.equals(getResources().getString(R.string.edit_item_prompt))) s = "";  
            	mItem.item = s;

            	s = txtDescription.getText().toString().trim();
            	if(s.equals(getResources().getString(R.string.edit_description_prompt))) s = "";  
            	mItem.description = s;
            	
            	s = txtTags.getText().toString().trim();
            	if(s.equals(getResources().getString(R.string.edit_tags_prompt))) s = "";  
            	mItem.tags = s;
            	
            	// other fields are updated when their respective Activity returns
            	// e.g. image field is updated when user returns from TakeImage activity

            	checkAndSave();
            } 
            catch (Exception e) 
            {
                Logger.log(e);
            }
    		break;
    		
    		
    	case R.id.btnBack: 
    		
    		setResult(RESULT_CANCELED);
    		finish();
    		break;
    	}
    }

    
    
    
	// ------------------------------------------
    // start image capture activity
	// ------------------------------------------
	private void startCamera()
	{
        try 
        {
      	  	// image capture discussions:
      	  	// http://code.google.com/p/android/issues/detail?id=1480
        	// http://stackoverflow.com/questions/649057/how-do-i-save-data-from-camera-to-disk-using-mediastore-on-android
      	  	Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      	  	
      	  	//
      	  	// EXTRA_OUTPUT
      	    // if this is specified the Intent does not return when clicking the 'attach' button 
      	  	// therefore have to do with low resolution provided without EXTRA_OUTPUT...
      	  	intent.putExtra(MediaStore.EXTRA_OUTPUT, Media.getTmpImageUri()); 

      	  	
      	  	startActivityForResult(intent, R.id.btnCamera); 
        } 
        catch (Exception e) 
        {
            Logger.log(e);
        }
	}
	
	
	
	
	// ------------------------------------------
    // start audio recorder activity
	// ------------------------------------------
	private void startRecorder()
	{
	   	if(CB.isTMobilePulse())
		{
			// -------------------------------
			// ***Pulse work-around
			// -------------------------------
        	new AlertDialog.Builder(ActivityEdit.this)
            .setMessage("After recording, hit your phone's Back button to leave recorder and attach audio.")
            .setPositiveButton("OK", new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialog, int whichButton) 
                {
                    try 
                    {
                    	Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
                    	startActivityForResult(intent, R.id.btnRecord);
                    } 
                    catch (Exception e) 
                    {
                        Logger.log(e);
                    }
                } 
            })
            .show();
		}
	   	else
	   	{
	        try 
	        {
	        	Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
	        	startActivityForResult(intent, R.id.btnRecord);
	        } 
	        catch (Exception e) 
	        {
	            Logger.log(e);
	        }
	   	}
	}
	
	
	
	
	// ------------------------------------------
    // start browser activity to select website
	// ------------------------------------------
	private void startBrowser()
	{
        try 
        {
        	Intent intent = new Intent(this, ActivityHyperlink.class);
      	  	intent.putExtra("url", getDefaultLink()); 
        	startActivityForResult(intent, R.id.btnBrowse);
        } 
        catch (Exception e) 
        {
            Logger.log(e);
        }
	}

	
	// ------------------------------------------
    // build default search string
	// ------------------------------------------
	private String getDefaultLink()
	{
    	String url = CB.getSearchEngine();
        try 
        {
        	url += "?q=" + URLEncoder.encode(txtItem.getText().toString().trim(), CB.ENCODING);
        } 
        catch (Exception e) 
        {
            Logger.log(e);
        }
        return url;
	}
	
	
	
	
	// ------------------------------------------
    // check if new mItem values make sense
	// ------------------------------------------
	private void checkAndSave()
	{
		// ----------------------
		// mandatory / error
		// ----------------------
		if(mItem.item.length() == 0) 
		{
	    	new AlertDialog.Builder(ActivityEdit.this)
	        .setMessage("Please enter a word.")
	        .setPositiveButton("OK", new DialogInterface.OnClickListener() 
	        {
	                public void onClick(DialogInterface dialog, int whichButton) 
	                {
	                	// do nothing
	                } 
	        }).show();
	    	
	    	return;
		}

		// ----------------------
		// warnings
		// ----------------------
		StringBuffer message = new StringBuffer();

		// item spelling changed?
		if((mBackupItem._id >= 0) &&(!mItem.item.equals(mBackupItem.item)))
		{
			message.append("You changed the spelling of this word");
		}

		// no description
		if(mItem.description.length() == 0)
		{
			if(mBackupItem.description.length() > 0)
			{
				if(message.length()>0)   message.append(", removed the description");
				else					 message.append("You removed the description");
			}
//			else										
//			{
//				if(message.length()>0)   message.append(", did not enter a description");
//				else					 message.append("You did not enter a description");
//			}
		}
		
		// check tags...
		int nRemovedTags = 0;
		StringBuffer sbRemovedTags = new StringBuffer();
		String[] t = mBackupItem.tags.split(" ");
		for(int i=0; i<t.length; i++)
		{
			if(!mItem.tags.contains(t[i]))
			{
				nRemovedTags++;
				if(sbRemovedTags.length() > 0) sbRemovedTags.append(" ");
				sbRemovedTags.append(t[i]);
			}
		}
		if(nRemovedTags > 0)
		{
			if(message.length()>0) message.append(" and removed tag");
			else                   message.append("You removed tag");
			if(nRemovedTags > 1)   message.append("s");
			message.append(" '").append(sbRemovedTags).append("'");
		}
//		else if(mItem.tags.length() == 0)
//		{
//			if(message.length()>0) message.append(" and did not enter any tags");
//			else                   message.append("You did not enter any tags");
//		}
		if(message.length()>0) message.append(". Are you sure?");


		if(message.length() > 0)
		{
	    	new AlertDialog.Builder(ActivityEdit.this)
	        .setMessage(message.toString())
	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() 
	        {
	                public void onClick(DialogInterface dialog, int whichButton) 
	                {
	                	saveItem();
	                } 
	        })
	        .setNegativeButton("No", new DialogInterface.OnClickListener() 
	        {
	                public void onClick(DialogInterface dialog, int whichButton) 
	                {
	                	// do nothing
	                } 
	        }).show();
		}
		else
		{
			// we're ready to save. Amend default link if empty.
			if(mItem.link.length()==0) mItem.link = getDefaultLink();
			
			// save this item
			saveItem();
		}
	}
	

	
	
	
	// ------------------------------------------
    // asynchronously save item to server
	// 1 - show ProgressDialog
	// 2 - set up handler to update UI
	// 3 - start thread to save data
	// ------------------------------------------	
    protected void saveItem()
	{
		mProgress = ProgressDialog.show(this, null, "saving, please wait...", true, false);

	    // Update UI (should not be done on asynchronous thread). 
		mHandler = new Handler()
		{
	        public void handleMessage(Message msg) 
	        {
	        	mProgress.dismiss();
	        	if(DB.errorState())
	        	{
	            	new AlertDialog.Builder(ActivityEdit.this)
	                .setMessage(DB.getLastErrorMessage(ActivityEdit.this))
	                .setPositiveButton("OK", new DialogInterface.OnClickListener() 
	                {
	                        public void onClick(DialogInterface dialog, int whichButton) 
	                        {
	                        	// mww: do not exit on network error because
	                        	// all editing is lost then. Rather revert to
	                        	// edit state and leave it to the user to
	                        	// try saving again or cancel!
	                        	
	        	        		// setResult(RESULT_CANCELED);
	                        	// ActivityEdit.this.finish();
	                        } 
	                }).show();
	        	}
	        	else
	        	{
	        		setResult(RESULT_OK);
	        		ActivityEdit.this.finish();
	        	}
            }
	    };

	    // Asynchronous:
		// refresh Item cursor with mTag and mSearch values, 
		// and generate an initial TagList if necessary
		new Thread(new Runnable()
		{
			public void run()
			{
				mItem._id = DB.putItem(mItem, ActivityEdit.this);
				mHandler.sendEmptyMessage(0);
			}
		}).start();
	}

    
    
	

	// ------------------------------------------
    // mww 06/2010 v.4 menu and preferences
    // create and listen to menu
	// ------------------------------------------
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.basic, menu);
		return true;
	}
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch(item.getItemId())
		{
		case R.id.mneSettings:
			 startActivity(new Intent(this, ActivitySettings.class));
			 return true;

		case R.id.mneAbout:
			 final TextView message = new TextView(this);
		     final SpannableString s = new SpannableString(getText(R.string.about_text));
			 Linkify.addLinks(s, Linkify.WEB_URLS);
			 message.setText(s);
			 message.setMovementMethod(LinkMovementMethod.getInstance());

			 new AlertDialog.Builder(this)
			 .setTitle(R.string.about_title)
			 .setIcon(R.drawable.icon)
			 .setPositiveButton("OK", null)
			 .setView(message)
			 .show();
        	 
			 return true;

		case R.id.mneHelp:
			 startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(CB.getHelpPage(this)))); 
			 return true;
		}
		return false;
	}

	

    
    
    
    // ------------------------------------------------------------------------------
    private File mPulseLastRecording; // Hack for T-Mobile Pulse see below (***Pulse) 
    // ------------------------------------------------------------------------------
    
    
	// ------------------------------------------
    // callback for sub-activities
	// ------------------------------------------
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
         super.onActivityResult(requestCode, resultCode, data);

         Logger.log(TAG + ".onActivityResult()");
         Logger.log("requestCode", requestCode);
         Logger.log("resultCode", resultCode);
         
         
         switch(requestCode)
         {
         
         case R.id.btnCamera:

        	 if (resultCode == Activity.RESULT_OK)
   	      	 {
        		 
        		 Bitmap bm = Media.getTmpImage(64, 48);
    	   		 if(bm!=null)
    	   		 {
    				 mItem.image = Media.getTmpImageUri().toString();
    				 Logger.log("tmp.image.URI", mItem.image);

    				 ImageView preview = (ImageView)findViewById(R.id.imgImage);
    				 preview.setImageBitmap(bm);
    	   		 }
    	   		 else Logger.log("onActivityResult: bm is null");                 
   	      	 }
        	 break;
             
         case R.id.btnRecord:

        	 /* ***Pulse
        	  * 
        	  * We use the Intent "MediaStore.Audio.Media.RECORD_SOUND_ACTION" to record audio for 
        	  * attachment to entries. The standard behaviour of this intent is to 
        	  * 1) display a recording screen with Record/Stop/Play buttons, and 
        	  * 2) give the user a coice to "Use this recording" or "Cancel" after recording something.
        	  * 
        	  * Unfortunately the T-Mobile Pulse seems to have "customised" this intent. 
        	  * The Pulse dor *not* give users a choice to "Use this recording" or "Cancel". 
        	  * Instead, users have to press the Menu button and then choose from a number of 
        	  * options like "Share", "Set as Ringtone", ...
        	  * 
        	  * This forces us to work around the Pulse "customisation". 
        	  * 
        	  * We know from logcat info and phone inspection that
        	  * - we can identify the Pulse
        	  * - all recordings are stored in SDCard/Recordings/ 
        	  * - recorded audio files follow this naming scheme: "recordingYYYMMDD_NNN.amr"
        	  * - the intent always returns requestCode=R.id.btnRecord resultCode=0
        	  * 
        	  * Based on this information we now
        	  * - check if it's a Pulse phone
        	  * - identify the youngest recording in SDCard/Recordings/ 
        	  * - verify that it is not older than <threshold> milliseconds 
        	  * - display an alert asking whether to use the recording or not
        	  * 
        	  * Search for CB.isTMobilePulse() to track down all Pulse Hacks!
        	  * 
        	  */
        	 if(CB.isTMobilePulse())
        	 {
        		Logger.log("Start work-around for audio recording on T-Mobile Pulse");
        		int MAX_REC_AGE = 60000; // max age of recordings to be considered 'current'
        		
        		// locate folder where Pulse stores recordings
        		File recordings = new File(Environment.getExternalStorageDirectory(), "Recordings");
        		if(recordings.exists() && recordings.isDirectory())
        		{
        			// get newest recording
        			mPulseLastRecording = null;
        			long pulse_last_modified = 0;
        			File recs[] = recordings.listFiles();
        			for(int i=0; i<recs.length; i++)
        			{
        				long m = recs[i].lastModified();
        				if(m > pulse_last_modified)
        				{
        					pulse_last_modified = m;
        					mPulseLastRecording = recs[i];
        				}
        			}
        			
        			// see if last recording is 'current'
        			if(mPulseLastRecording != null)
        			{
            			Time now = new Time();
            			now.setToNow(); 
            			
        				long age = now.toMillis(false) - pulse_last_modified;
        				Logger.log("rec age", age);
        				
        				if(age < MAX_REC_AGE)
        				{
        					// -------------------------------
        					// OK we have a current recording.
        					// does the user want to use it?
        					// -------------------------------
			            	new AlertDialog.Builder(ActivityEdit.this)
			                .setMessage("Use recording for this entry?")
			                .setPositiveButton("Use recording", new DialogInterface.OnClickListener() 
			                {
		                        public void onClick(DialogInterface dialog, int whichButton) 
		                        {
		   	       				 	if(Media.retrieveAudioFromPhone(mPulseLastRecording.getAbsolutePath()))
		   	       				 	{
		   	       				 		mItem.audio = Media.getTmpAudioUri().toString();
		   	       				 		Logger.log("Media.getTmpAudioUri()", mItem.audio);
			
		   	       				 		ImageView preview = (ImageView)findViewById(R.id.imgAudio);
		   	       				 		preview.setImageResource(R.drawable.edit_audio);
		   	       				 	}
		                        } 
			                })
			                .setNegativeButton("Discard", null).show();
        				}
        			}
        		}
        		Logger.log("End work-around for audio recording on T-Mobile Pulse");
        	 }	
        	 else
        	 {
        		 //
        		 // default behaviour with AudioRecorder showing "Use this" and "Cancel" buttons
        		 //
	        	 if ((resultCode == Activity.RESULT_OK) && data != null)
	   	      	 {
	        		 try
	        		 {
	        			 //
	        			 // The default SoundRecorder stores recorded audio as .3gpp files
	        			 // on the SD card (root) and creates an entry in the MediaStore
	        			 // referencing this file. The Activity then returns an uri_with_id 
	        			 // that gives direct access to the record in the MediaStore database 
	        			 // e.g. content://media/external/audio/media/2  ('2' is the _id)
	        			 // We use this uri to retrieve the MediaStore column and find
	        			 // out the path to the actual audio file. This is then copied to
	        			 // our own Media.tmp_audio_path (to avoid the user accidentally
	        			 // deleting it) from there it is uploaded to the server. 
	        			 // 
	            		 Logger.log("data.getData()", data.getDataString());
	
	            		 String[] cols = new String[] {MediaStore.MediaColumns.DATA};   			 
	        			 Cursor c = getContentResolver().query(data.getData(), cols, null, null, null);
	       				 c.moveToFirst();
						 String audio_file = c.getString(0);
						 c.close();
						 
	       				 if(Media.retrieveAudioFromPhone(audio_file))
	       				 {
	        				 mItem.audio = Media.getTmpAudioUri().toString();
	        				 Logger.log("Media.getTmpAudioUri()", mItem.audio);
	
	        				 ImageView preview = (ImageView)findViewById(R.id.imgAudio);
	        				 preview.setImageResource(R.drawable.edit_audio);
	       				 }
	        		 }
	        		 catch(Exception e)
	        		 {
	        			 Logger.log(e);
	        		 }
	   	      	 }
        	 }
        	 break;
             
         case R.id.btnBrowse:

        	 if (resultCode == Activity.RESULT_OK)
   	      	 {
        		 try
        		 {
            		 String url = data.getExtras().getString("url");
            		 Logger.log("selected URL", url);
            		 
            		 mItem.link = url;

    				 ImageView preview = (ImageView)findViewById(R.id.imgLink);
    				 preview.setImageResource(R.drawable.edit_link);
        		 }
        		 catch(Exception e)
        		 {
        			 Logger.log(e);
        		 }
   	      	 }
        	 break;
         }
    }

    
    

	public void onFocusChange(View v, boolean hasFocus)
	{
        Logger.log(TAG + ".onFocusChange()");

		EditText edt = (EditText)v;
		String txt = edt.getText().toString().trim();

        if(hasFocus)
		{
			if(txt.equals(getResources().getString(R.string.edit_item_prompt)) 
			|| txt.equals(getResources().getString(R.string.edit_description_prompt)) 
			|| txt.equals(getResources().getString(R.string.edit_tags_prompt)))
			{
				edt.setText("");
			}
		}
		else
		{
			if(txt.length() == 0)
			{
				if(edt.equals(txtItem)) edt.setText(R.string.edit_item_prompt);
				else if(edt.equals(txtDescription)) edt.setText(R.string.edit_description_prompt);
				else if(edt.equals(txtTags)) edt.setText(R.string.edit_tags_prompt);
			}
			else
			{
				if(edt.equals(txtItem))
				{
					if((mItem._id < 0) && (mLookupItem._id < 0)) 
					{
						// -------------------------------------------
						// do background check if item already exists
						// -------------------------------------------
						
						mLookupItem.item = txt;

						mHandler = new Handler()
						{
					        public void handleMessage(Message msg) 
					        {
					        	if(mLookupItem._id > 0) 
					        	{
					        		String s = "The term '" 
					        			     + mLookupItem.item
					        			     + "' is already in the database."
					        			     + " Press VIEW to see the current entry."
					        			     + " Press NEW to create a new entry.";
					            	new AlertDialog.Builder(ActivityEdit.this)
					                .setMessage(s)
					                .setPositiveButton("View", new DialogInterface.OnClickListener() 
					                {
				                        public void onClick(DialogInterface dialog, int whichButton) 
				                        {
						                	// display stored item in Detail view 
				                			Intent detail = new Intent(ActivityEdit.this, ActivityDetail.class);
				                			detail.putExtra("Item._id", mLookupItem._id);
				                			startActivity(detail);
				                			
				                			// remove us from activity stack
				                			ActivityEdit.this.setResult(RESULT_CANCELED);
				                        	ActivityEdit.this.finish();
				                        } 
					                })
					                .setNegativeButton("New", new DialogInterface.OnClickListener() 
					                {
				                        public void onClick(DialogInterface dialog, int whichButton) 
				                        {
				        	        		// do nothing. we won't check again as 
				                        	// LookupItem._id is set to a valid id
				                        } 
					                }).show();
					        	}
				            }
					    };

					    // Asynchronous: look up item currently in txtItem field
						new Thread(new Runnable()
						{
							public void run()
							{
								Cursor c = DB.getItem(mLookupItem.item);
						    	if(!DB.errorState())
						    	{
						    		c.moveToFirst();
						    		mLookupItem._id = c.getLong(0);
						    	}

								mHandler.sendEmptyMessage(0);
							}
						}).start();
					}
				}
			}
		}		
	}
}
